package com.ruibang.glass.portal.service;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.portal.constant.UserErrorCode;
import com.ruibang.glass.portal.domain.ButtonReq;
import com.ruibang.glass.portal.domain.Tree;
import com.ruibang.glass.portal.entity.MenuEntity;
import com.ruibang.glass.portal.mapper.MenuMapper;
import com.ruibang.glass.portal.mapper.RoleMenuMapper;
import com.ruibang.glass.portal.util.BuildTree;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.model.ResultBody;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MenuService extends ServiceImpl<MenuMapper,MenuEntity> implements IService<MenuEntity> {

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RedisSingleService redisService;

    /**
     * 保存菜单
     *
     * @return
     */
    public ResultBody<Void> saveMenu(MenuEntity entity) {
        List<MenuEntity> menuEntities = baseMapper.listChildMenu(entity.getParentId());
        entity.setOrderNum(Optional.ofNullable(menuEntities).isPresent() ? menuEntities.size() : 1);
        entity.setParentId(entity.getParentId() == null ? "0" : entity.getParentId());
        entity.setStatus(entity.getStatus()==null? 1 : entity.getStatus() );
        this.save(entity);
        return ResultBody.success();

    }


    /**
     * 根据菜单id获取菜单
     *
     * @param menuId
     * @return
     */
    public ResultBody<MenuEntity> getMenu(String menuId) {
        if (StringUtils.isBlank(menuId)) {
            return ResultBody.fail(UserErrorCode.PARAM_ERROR.getCode(), UserErrorCode.PARAM_ERROR.getMsg());
        }
        MenuEntity menuEntity = baseMapper.get(menuId);
        if (!Optional.ofNullable(menuEntity).isPresent()) {
            return ResultBody.fail(UserErrorCode.NOT_EXISTS.getCode(), UserErrorCode.NOT_EXISTS.getMsg());
        }
        MenuEntity parentInfo = baseMapper.get(menuEntity.getParentId());
        menuEntity.setParentName(Optional.ofNullable(parentInfo).isPresent() ? parentInfo.getMenuName() : "根目录");
        return ResultBody.success(menuEntity);

    }

    /**
     * 获取菜单树
     *
     * @return
     */
    public ResultBody<Tree<MenuEntity>> getTree() {
        List<Tree<MenuEntity>> trees = new ArrayList<Tree<MenuEntity>>();
        List<MenuEntity> menus = baseMapper.getMenuList();

        Optional.ofNullable(menus).ifPresent(a -> {
            a.forEach(m -> {
                Tree<MenuEntity> tree = new Tree();

                Map<String, Object> attributes = new HashMap<>();
                attributes.put("url", m.getUrl());
                attributes.put("type", m.getType());
                attributes.put("status", m.getStatus());
                attributes.put("order_num", m.getOrderNum());
                attributes.put("icon", m.getIcon());

                tree.setAttributes(attributes);
                tree.setId(m.getMenuId());
                tree.setParentId(m.getParentId());
                tree.setText(m.getMenuName());

                tree.setDisabled(Integer.valueOf(1).equals(m.getStatus()) ? false : true);
                trees.add(tree);
            });

        });
        Tree<MenuEntity> t = BuildTree.build(trees);
        return ResultBody.success(t);
    }

    /**
     * 根据角色id获取菜单树
     *
     * @return
     */
    public ResultBody<Tree<MenuEntity>> getTreeByRoleId(String roleId) {
        if (roleId == null) {
            return ResultBody.fail(UserErrorCode.PARAM_ERROR.getCode(), UserErrorCode.PARAM_ERROR.getMsg());
        }

        // 根据roleId查询权限
        List<MenuEntity> menus = baseMapper.getMenuList();

        List<String> menuIds = new ArrayList();
        ;
        Optional.ofNullable(roleMenuMapper.getMenuIdByRoleId(roleId)).ifPresent(menuIdList -> {
            menuIds.addAll(menuIdList);
        });

        List<Tree<MenuEntity>> trees = new ArrayList();

        Optional.ofNullable(menus).ifPresent(a -> {
            a.forEach(m -> {
                Tree<MenuEntity> tree = new Tree();
                tree.setId(m.getMenuId());
                tree.setParentId(m.getParentId().toString());
                tree.setText(m.getMenuName());
                boolean state = false;
                if (menuIds.contains(m.getMenuId())) {
                    state = true;
                }

                Map<String, Object> attributes = new HashMap<>();
                attributes.put("url", m.getUrl());
                attributes.put("type", m.getType());
                attributes.put("status", m.getStatus());
                attributes.put("order_num", m.getOrderNum());
                attributes.put("icon", m.getIcon());
                tree.setAttributes(attributes);
                tree.setDisabled(Integer.valueOf(1).equals(m.getStatus()) ? false : true);
                tree.setChecked(state);
                trees.add(tree);
            });
        });
        return ResultBody.success(BuildTree.build(trees));
    }

    /**
     * 根据用户id获取菜单树
     *
     * @param userId
     * @return
     */
    public ResultBody<Tree<MenuEntity>> getTreeByUserId(String userId) {
        List<Tree<MenuEntity>> trees = new ArrayList();
        List<MenuEntity> menus = baseMapper.getMenuByUserId(userId);

        Optional.ofNullable(menus).ifPresent(a -> {
            a.forEach(m -> {
                Tree<MenuEntity> tree = new Tree();
                tree.setId(m.getMenuId());
                tree.setParentId(m.getParentId());
                tree.setText(m.getMenuName());

                Map<String, Object> attributes = new HashMap<>();
                attributes.put("url", m.getUrl());
                attributes.put("type", m.getType());
                attributes.put("status", m.getStatus());
                attributes.put("order_num", m.getOrderNum());
                attributes.put("icon", m.getIcon());
                tree.setDisabled(Integer.valueOf(1).equals(m.getStatus()) ? false : true);
                tree.setAttributes(attributes);
                trees.add(tree);

            });
        });
        Tree<MenuEntity> t = BuildTree.build(trees);
        return ResultBody.success(t);
    }

    /**
     * 删除菜单
     *
     * @param menuId
     * @return
     */
    public ResultBody deleteMenuById(String menuId) {
        List<MenuEntity> menuEntities = baseMapper.listChildMenu(menuId);
        if (Optional.ofNullable(menuEntities).isPresent() && menuEntities.size() > 0) {
            return ResultBody.fail(UserErrorCode.NOT_DELET_ERROR_MENU.getCode(), UserErrorCode.NOT_DELET_ERROR_MENU.getMsg());
        }
        this.removeById(menuId);
        roleMenuMapper.delByMenuId(menuId);
        return ResultBody.success();
    }

    /**
     * 根据角色查询某个菜单下的按钮信息
     *
     * @return
     */
    public ResultBody<List<MenuEntity>> getButtonInfo(ButtonReq buttonReq) {
        if (null == buttonReq || null == buttonReq.getMenuId() || CollectionUtils.isEmpty(buttonReq.getRoleIds()))
            return ResultBody.fail(UserErrorCode.PARAM_ERROR.getCode(), UserErrorCode.PARAM_ERROR.getMsg());

        //查询当前菜单下的所有按钮
        List<MenuEntity> buttonList = baseMapper.listChildButtonByMenuId(buttonReq.getMenuId());
        if (CollectionUtils.isNotEmpty(buttonList)) {
            //根据角色id和菜单id查询可访问的按钮
            List<String> usableMenuIdList = baseMapper.getUsableButton(buttonReq);
            if(CollectionUtils.isNotEmpty(usableMenuIdList)){
                for(MenuEntity menu : buttonList){
                    if(usableMenuIdList.contains(menu.getMenuId()))
                        menu.setEnabled(true);
                }
            }
        }
        return ResultBody.success(buttonList);
    }

    /***
     * 根据菜单名称获取菜单Id
     * @param menuName
     * @return
     */
    public String getMenuIdByMenuName(String menuName){
        return baseMapper.getMenuIdByMenuName(menuName);
    }

}
